from datetime import datetime
from fastapi import HTTPException
import logging
from pydantic import ValidationError
from app.models.user import Expectation, Resume, User, UserRole
from app.schemas.user import ExpectationUpdate, UserCreate, UserUpdate
import os
from app.settings import MEDIA_BASE_PATH
from fastapi import APIRouter, Depends, File, UploadFile, HTTPException, status


async def create_user(user: UserCreate):
    """
    创建新用户
    参数:
    - user: UserCreate, 包含用户信息的请求体
    
    返回:
    - 创建的用户对象
    """
    return await User.create_user(
        username=user.username,
        password=user.password,
        email=user.email,
        phone=user.phone,
        gender=user.gender,
        real_name=user.real_name,
        role=user.role,
        is_active=user.is_active,
        job_seeker_status=user.job_seeker_status
    )


async def upload_avatar(username: str, file_content: bytes) -> str:
    """
    上传用户头像
    
    参数:
    - username: str, 用户名
    - file_content: bytes, 文件内容
    
    返回:
    - 返回头像的相对路径
    """

    
    # 创建avatar_img目录如果不存在
    avatar_dir = os.path.join(MEDIA_BASE_PATH, "media","avatar_img")
    os.makedirs(avatar_dir, exist_ok=True)
    
    # 生成文件名和路径
    file_name = f"{username}.jpg"
    file_path = os.path.join(avatar_dir, file_name)
    
    # 保存文件
    with open(file_path, "wb") as f:
        f.write(file_content)
        
    # 返回相对路径
    return os.path.join("avatar_img", file_name)

async def get_user_by_id(user_id: int) -> User:
    """
    根据用户ID获取用户详情
    
    参数:
    - user_id: int, 用户ID
    
    返回:
    - 用户对象
    
    异常:
    - 404 Not Found: 如果用户不存在时抛出
    """
    user = await User.get_or_none(id=user_id)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="用户不存在"
        )
    return user


async def update_user(user_id: int, user_update: UserUpdate) -> User:
    """
    更新用户信息
    
    参数:
    - user_id: int, 用户ID
    - user_update: UserUpdate, 需要更新的用户信息
    
    返回:
    - 更新后的用户对象
    
    异常:
    - 404 Not Found: 如果用户不存在时抛出
    - 400 Bad Request: 如果更新数据验证失败时抛出
    """
    try:
        # 获取用户
        user = await User.get_or_none(id=user_id)
        if not user:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="用户不存在"
            )
        
        # 验证并更新用户信息
        update_data = user_update.model_dump(exclude_unset=True)
        if 'password' in update_data:
            # 如果更新了密码，需要加密处理
            update_data['password'] = get_password_hash(update_data['password'])
        
        await user.update_from_dict(update_data)
        await user.save()
        
        # 更新更新时间
        user.updated_at = datetime.now()
        await user.save()
        
        return user
        
    except ValidationError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e)
        )

def get_password_hash(password: str) -> str:
    """
    对密码进行哈希处理
    
    参数:
    - password: str, 原始密码
    
    返回:
    - str: 哈希后的密码
    """
    from passlib.context import CryptContext
    pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
    return pwd_context.hash(password)


async def get_users_by_role(role: UserRole, skip: int = 0, limit: int = 10) -> list[User]:
    """
    根据角色获取用户列表
    
    参数:
    - role: UserRole, 用户角色
    - skip: int, 跳过的记录数，用于分页
    - limit: int, 每页显示的记录数
    
    返回:
    - list[User]: 用户列表
    """
    return await User.filter(role=role).offset(skip).limit(limit).all()



async def upload_resume(username: str, file_content: bytes) -> str:
    """
    上传用户简历文件
    
    参数:
    - username: str, 用户名
    - file_content: bytes, 简历文件内容
    
    返回:
    - str: 简历存储路径
    """
    try:
        # 获取用户对象
        user = await User.get_or_none(username=username)
        if not user:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="用户不存在"
            )
        
        # 创建简历存储目录
        resume_dir = os.path.join(MEDIA_BASE_PATH, "media", "resumes")
        os.makedirs(resume_dir, exist_ok=True)
        
        # 使用用户名和时间戳作为文件名，避免重复
        timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
        file_name = f"{username}_{timestamp}.pdf"
        file_path = os.path.join(resume_dir, file_name)
        
        # 保存文件
        with open(file_path, "wb") as f:
            f.write(file_content)
        
        # 创建或更新简历记录
        resume = await Resume.get_or_none(user=user)
        if resume:
            # 如果存在旧简历，先删除旧文件
            if os.path.exists(resume.resume_url):
                os.remove(resume.resume_url)
            resume.resume_url = file_path
            await resume.save()
        else:
            await Resume.create(user=user, resume_url=file_path)
        
        return file_path
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"简历上传失败: {str(e)}"
        )


async def create_expectation(user_id: int, expectation: ExpectationUpdate) -> Expectation:
    """
    创建用户求职期望信息
    
    参数:
    - user_id: int, 用户ID
    - expectation: ExpectationUpdate, 求职期望信息
    
    返回:
    - Expectation: 创建的求职期望对象
    
    异常:
    - 404 Not Found: 如果用户不存在时抛出
    - 400 Bad Request: 如果期望薪资为负数时抛出
    """
    # 检查用户是否存在
    user = await User.get_or_none(id=user_id)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="用户不存在"
        )
    
    # 验证期望薪资
    if expectation.money < 0:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="期望薪资不能为负数"
        )
    
    # 创建求职期望记录
    expectation_data = expectation.model_dump()
    try:
        return await Expectation.create(user_id=user_id, **expectation_data)
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"创建求职期望失败: {str(e)}"
        )
    
async def update_expectation(user_id: int, expectation: ExpectationUpdate) -> Expectation:
    """
    更新用户求职期望信息
    
    参数:
    - user_id: int, 用户ID
    - expectation: ExpectationUpdate, 求职期望更新信息
    
    返回:
    - Expectation: 更新后的求职期望对象
    
    异常:
    - 404 Not Found: 如果用户或期望不存在时抛出
    - 400 Bad Request: 如果期望薪资为负数时抛出
    - 500 Internal Server Error: 如果更新失败时抛出
    """
    # 检查用户是否存在
    user = await User.get_or_none(id=user_id)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="用户不存在"
        )
    
    # 检查期望是否存在
    existing_expectation = await Expectation.get_or_none(user_id=user_id)
    if not existing_expectation:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="求职期望不存在"
        )
    
    # 验证期望薪资
    if expectation.money and expectation.money < 0:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="期望薪资不能为负数"
        )
    
    # 更新记录
    update_data = expectation.model_dump(exclude_unset=True)
    if not update_data:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="至少需要一个有效字段进行更新"
        )
    
    try:
        await existing_expectation.update_from_dict(update_data)
        await existing_expectation.save()
        return existing_expectation
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"更新求职期望失败: {str(e)}"
        )


